using System;
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml.Serialization;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.WebPartPages;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages.Communication;

namespace PhilWicklund.com.ListItemArchiver
{
	/// <summary>
	/// Description for ListItemDesplayer. 
	/// </summary>
	[DefaultProperty("Text"),
		ToolboxData("<{0}:ArchivedListItemDisplayerWP runat=server></{0}:ArchivedListItemDisplayerWP>"),
		XmlRoot(Namespace = "PhilWicklund.com.ListItemArchiver")]
	public class ArchivedListItemDisplayerWP : Microsoft.SharePoint.WebPartPages.WebPart, ICellConsumer
	{
		//Date recieved from filter on
		private DateTime dateToShow;
		private DateTime today = DateTime.Now;
		private string listName = "";
		private string fieldName = "";
		private const string defaultText = "";
		
		public ArchivedListItemDisplayerWP() 
		{
			dateToShow = new DateTime(today.Year, today.Month, today.Day);
		}

		#region Properties
		[Browsable(false),
		Category("List Properties"),
		DefaultValue(defaultText),
		Description("hidden."),
		FriendlyName("List Name"),
		ReadOnly(false),
		WebPartStorage(Storage.Personal)
		]
		public string ListName
		{
			get{return listName;}
			set{listName = value;}
		}
			
		[Browsable(true),
		Category("List Properties"),
		DefaultValue(defaultText),
		Description("Enter the field name to rend in addition to the title of the listitem."),
		FriendlyName("Optional Field To Render"),
		ReadOnly(false),
		WebPartStorage(Storage.Personal)
		]
		public string FieldName
		{
			get{return fieldName;}
			set{fieldName = value;}
		}

		public override ToolPart[] GetToolParts()
		{
			try
			{
				//Number of toolparts to display
				ToolPart[] toolparts = new ToolPart[3];
				
				ArchivedListItemDisplayerTP liatp = new ArchivedListItemDisplayerTP(ListName);
				toolparts[0] = liatp;

				CustomPropertyToolPart cptp = new CustomPropertyToolPart();
				cptp.Expand("List Properties");
				toolparts[1] = cptp;

				WebPartToolPart wptp = new WebPartToolPart();
				toolparts[2] = wptp;

				return toolparts;
			}
			catch
			{
				return base.GetToolParts ();
			}
		}
		#endregion
		
		/// <summary>
		/// Render this Web Part to the output parameter specified.
		/// </summary>
		/// <param name="output"> The HTML writer to write out to </param>
		protected override void RenderWebPart(HtmlTextWriter output)
		{
			try
			{
				
					EnsureChildControls();
					//If we are connected then display all child controls
				if (_cellConnectedCount > 0)
				{	
					if (listName != "") 
					{		
						string month = MonthStringConverter.getMonthString(dateToShow.Month);
						RenderChildren(output);
						output.Write("<div class='ms-WPTitle'>" + month + " " + dateToShow.Year + " Archive</div>");

						SPWeb web = SPControl.GetContextWeb(Context);
						SPList list = web.Lists[listName];

						bool listingsFound = false;
						foreach (SPListItem item in list.Items)
						{
							const string slash = "/";
							string [] creationDateArray = item["Created"].ToString().Split(slash.ToCharArray());
							month = creationDateArray[0];
							string day = creationDateArray[1];
							string year = creationDateArray[2].Substring(0,4);
							DateTime itemCreatedDate = new DateTime(int.Parse(year), int.Parse(month), int.Parse(day));

							if (itemCreatedDate.Year == dateToShow.Year &&
								itemCreatedDate.Month == dateToShow.Month)
							{
									output.WriteLine("<p><a href='" + web.Url + "/Lists/" + list.Title + "/DispForm.aspx?ID=" + item.ID + "'><b>" + item["Title"].ToString() + "</b></a><br>" + renderOptionalField(item) + "</p>");
								listingsFound = true;
							}
						}

						// If no news is found for current month (default) display message.
						if (listingsFound == false) 
						{
							output.Write("There are no items for this month");
						}
					}
					else
					{
						output.Write("Please select appropriate month.");
					}
				}
				else
				{
					//else display no connection message
					output.Write("NO CELL INTERFACE CONNECTION - PLEASE CONNECT THE LISTITEM ARCHIVER TO THIS WEBPART");
				}
			}
			 
			catch(Exception e)
			{
				output.WriteLine("Exception Occured -->> " + e);
			}
		}

		private string renderOptionalField(SPListItem item) 
		{
            string returnText = "";
			try 
			{
				returnText = item[FieldName].ToString();
			}
			catch {return String.Empty;}
			return returnText;
		}

		#region Connections
		//Step #1: Declare Connection events
		public event CellConsumerInitEventHandler CellConsumerInit;


		//Keep a count of ICell connections
		private int _cellConnectedCount = 0;

		//Cell information
		private string _cellName;
		private string _cellDisplayName;

		//EnsureInterfaces
		//Notification to the Web Part that is should ensure that all
		//its interfaces are registered using RegisterInterface.
		public override void EnsureInterfaces()
		{
			//Registers an interface for the Web Part.
			RegisterInterface("MyCellConsumerInterface_WPQ_",	//InterfaceName
				InterfaceTypes.ICellConsumer,					//InterfaceType
				WebPart.UnlimitedConnections,					//MaxConnections
				ConnectionRunAt.Server,				//RunAtOptions
				this,											//InterfaceObject
				"CellConsumerInterface_WPQ_",					//InterfaceClientRefC:\Projects\RSM Intranet\Web Parts Lib\ConachGroup.GODataSolutions.WebParts\SecuredLinksList\SecuredLinksListTP.cserence
				"Get Date",								//MenuLabel
				"Just a simple ICellConsumer");					//Description
		}

		//CanRunAt - called by framework to determine where a part can run.
		public override ConnectionRunAt CanRunAt()
		{
			//This Web Part can run on both the client and the server
			return ConnectionRunAt.Server;
		}

		//PartCommunicationConnect - Notification to the Web Part that it has been connected.
		public override void PartCommunicationConnect(string interfaceName,
			WebPart connectedPart,
			string connectedInterfaceName,
			ConnectionRunAt runAt)
		{
			
			//Must be a server-side part so need to create the Web Part's controls
			EnsureChildControls(); 

			//Check if this is my particular cell interface
			if (interfaceName == "MyCellConsumerInterface_WPQ_")
			{
				//Keep a count of the connections
				_cellConnectedCount++;
			}
		}

		//Step #5: PartCommunicationInit - Broadcast schema information regarding what this webpart expect to receive from the providing webpart
		public override void PartCommunicationInit()
		{
			//If the connection wasn't actually formed then don't want to send Init event
			if(_cellConnectedCount > 0)
			{
				//If there is a listener, send init event
				if (CellConsumerInit != null) // CellConsumerInit = EventHandler
				{
					//Need to create the args for the CellConsumerInit event
					CellConsumerInitEventArgs cellConsumerInitArgs = new CellConsumerInitEventArgs();
			
					//There are only two possible args, Name and Description of cell, or 'field'
					//Set the FieldNames
					cellConsumerInitArgs.FieldName = _cellName;
					cellConsumerInitArgs.FieldDisplayName = _cellDisplayName;

					//Fire the CellConsumerInit event.
					//This basically tells the Provider Web Part what type of
					//cell the Comsumer is expecting in the CellReady event.
					CellConsumerInit(this, cellConsumerInitArgs);
				}
			}
		}

		//Step #6: PartCommunicationMain - this method doesn't need to be implemented for the Consumer
		//because the Consumer doesn't have any events that need to be fired during this phase.


		

		
	
		//Step #8: Implement CellProviderInit Event Handler.
		public void CellProviderInit(object sender, CellProviderInitEventArgs cellProviderInitArgs)
		{
			//This is where the Consumer part could see what type of "Cell" the Provider
			//will be sending.
			//For this simple code example, this information is not used anywhere.
		}

		//Implement CellReady Event Handler. 
		//Set label text based on value from the CellProvider Web Part
		public void CellReady(object sender, CellReadyEventArgs cellReadyArgs)
		{
			//Set the label text to the value of the "Cell" that was passed by the Provider
			if(cellReadyArgs.Cell != null)
			{
				string receivedString = cellReadyArgs.Cell.ToString();
				if (receivedString != "") 
				{
					const string colon = ":";
					string [] listAndDate = receivedString.Split(colon.ToCharArray());
					if (listAndDate.Length != 2)
						throw new Exception("ERROR: Received Connection String is invalid");
					if (listAndDate[0] != "")
						listName = listAndDate[0];
					if (listAndDate[1] != "")
					{
						string date = listAndDate[1];
						const string slash = "/";
						string [] creationDateArray = date.Split(slash.ToCharArray());
						string month = creationDateArray[0];
						string day = creationDateArray[1];
						string year = creationDateArray[2].Substring(0,4);
						dateToShow = new DateTime(int.Parse(year), int.Parse(month), int.Parse(day));
					}
				}
			}
		}
		#endregion

		//Step #10 (Supporting Methods): CreateChildControls
		protected override void CreateChildControls()
		{
			_cellName = "Date";
			_cellDisplayName = "Date";
		}

	}
}
